local Widget = require("widgets/widget")
local Image = require("widgets/image")
local Easing = require("easing")

local half_x, half_y = RESOLUTION_X / 2, RESOLUTION_Y / 2
local screen_width, screen_height = TheSim:GetScreenSize()
local function WorldPosToScreenPos(x, z)
    local map_x, map_y = TheWorld.minimap.MiniMap:WorldPosToMapPos(x, z, 0)
    local screen_x = ((map_x * half_x) + half_x) / RESOLUTION_X * screen_width
    local screen_y = ((map_y * half_y) + half_y) / RESOLUTION_Y * screen_height
    return screen_x, screen_y
end

local s_util = require("libs/settingmanager")

local refreshflag
local AutoMapIcons = Class(Widget, function(self, mapscreen, iscave)
    Widget._ctor(self, "AutoMapIcons")
    self.root = mapscreen:AddChild(Widget("root"))
    self.icons = {}
    self.hide = false
    local MapWidgetOnUpdate = mapscreen.OnUpdate
    self.iscave = iscave or (TheWorld:HasTag("cave") and 1 or 0)
    -- print("注意:", self.iscave)
    local typescreen = tostring(mapscreen)
    if typescreen == "MapScreen" then
        mapscreen.OnUpdate = function(mapscreen, ...)
            MapWidgetOnUpdate(mapscreen, ...)
            local zoom = TheWorld.minimap.MiniMap:GetZoom()
            local scale = 0.85 - Easing.outExpo(zoom - 1, 0, 0.6, 8)
            for _, mapicon in pairs(self.icons) do
                local x, y = WorldPosToScreenPos(mapicon.x, mapicon.z)
                mapicon:SetPosition(x, y)
                mapicon:SetScale(scale or 1)
            end
        end
    elseif typescreen == "HUD" then
        mapscreen.OnUpdate = function(mapscreen, ...)
            MapWidgetOnUpdate(mapscreen, ...)
            if TheCamera and TheCamera.mindistpitch == 90 then
                self.root:Show()
                if not refreshflag then
                    -- 代码遗留问题，需要刷新两次
                    self:Refresh()
                    if not next(self.icons) then
                        self:Refresh()
                    end
                    refreshflag = true
                end
                for _, mapicon in pairs(self.icons) do
                    local x, y = TheSim:GetScreenPos(mapicon.x, 0, mapicon.z)
                    mapicon:SetPosition(x, y)
                end
            else
                refreshflag = nil
                self.root:Hide()
            end
        end
    end
    
    self:Refresh()
end)

function AutoMapIcons:SwitchHide()
    self.hide = not self.hide
    -- for _, mapicon in pairs(self.icons) do
        if self.hide then
            self.root:Hide()
        else
            self.root:Show()
        end
    -- end
end

local idata = require("QAQ/icondata")
function AutoMapIcons:AddMapIcon(id, pos_x, pos_y, altas, image)
    -- 这一步是为了适配旧版慕斯，虽然降低效率，但不可删除
    if type(altas)=="string" and altas:match("mod_boss")then
        altas = "images/shroomcake_moreicons.xml"
    end
    self.icons[id] = self.root:AddChild(Image(altas, image))
    self.icons[id].x = pos_x
    self.icons[id].z = pos_y
    self.icons[id]:SetScale(0.3)
end

local d_util = require "libs/datamanager"
function AutoMapIcons:Refresh()
    local w_data = require("libs/worldmanager"):GetWorldDataList("more_map_icons")
    local id_icons = {}
    local h_data = d_util:GetIconData()
    local tmip_path = resolvefilepath("images/customicobyysh.xml")
    local minimap_path = resolvefilepath("minimap/minimap_data.xml")
    -- 遍历最新数据，将没有的图标增加进显示
    for _, data in pairs(w_data)do
        if data.c and data.x and data.z and data.c == self.iscave then
            local id = data.c..data.x..data.z
            table.insert(id_icons, id)
            if not self.icons[id] then
                local info = data.atlas and data.image and data
                if not info then
                    if data.p then
                        local image = data.p..".tex"
                        local inv_altas = GetInventoryItemAtlas(image)
                        if TheSim:AtlasContains(tmip_path, image) then
                            info = { atlas= tmip_path, image = image }
                        elseif TheSim:AtlasContains(minimap_path, image) then
                            info = { atlas= minimap_path, image = image }
                        elseif inv_altas and TheSim:AtlasContains(inv_altas, image)  then
                            info = { atlas= inv_altas, image = image }
                        else
                            info = idata[data.p]
                        end
                    end
                end
                if info then
                    local a = info.atlas
                    local i = info.image
                    if a and i then
                        local has
                        for _, line in pairs(h_data)do
                            if line.a == a and line.i == i then
                                has = true
                                break
                            end
                        end
                        if not has then
                            self:AddMapIcon(id, data.x, data.z, a, i)
                        end
                    end
                end
            end
        end
    end
    -- 遍历显示，将不在最新数据中的图标都删除
    for id,_ in pairs(self.icons)do
        if not table.contains(id_icons, id) then
            self.icons[id]:Kill()
            self.icons[id] = nil
        end
    end
end


return AutoMapIcons
